*XB256 SOURCE CODE
*XB PATTERN TABLE AT >3000 TO >37FF		>06 TO VDP R4
*COLOR TABLE AT >3800 TO >3820			>E0 TO VDP R3
*SWAP SCREEN BUFFER >2C00 TO >2FFF
 
 
		
*********************
*SCRN2 expanded graphics screen (CF7)
*********************
SCRN2	MOV @SCRENE,R10
	JNE SCRN2Z
	BL @SCRN2A
SCRN2Z	B @RTN
 
SCRN2A	MOV R11,R10
	SETO @SCRENE
	BL @SWPSCR
	BYTE >00
	BYTE >0F
	BYTE >0C
	BYTE >00
	BYTE >01
	BYTE >0C
	BYTE >0D	Sets the enhanced 256 color screen
	BYTE >01
	BYTE >02
	BYTE >0D
	BYTE >0E
	BYTE >02
	
	DATA >0360
	DATA >0402
SC2CLR	DATA >07F4
	DATA 0		/
SC2DC	DATA >07F4		screen2 default color
*************************************
*SCRN1 is the normal screen in XB (CF7)
******************************	
SCRN1	MOV @SCRENE,R10
	JEQ SCRN2Z
	BL @SCRN1A
SCRNRT	JMP SCRN2Z
	
SCRN1A	CLR @SCRENE
SCRN1B	MOV R11,R10
	BL @SWPSCR
	BYTE >02
	BYTE >0E
	BYTE >0D
	BYTE >02
	BYTE >01
	BYTE >0D	Sets the normal XB screen
	BYTE >0C
	BYTE >01
	BYTE >00
	BYTE >0C
	BYTE >0F
	BYTE >00
	
	DATA >0320
	DATA >0400
SC1CLR	DATA >0717	screen color=cyan
	DATA 0		/
SC1DC	DATA >0717	screen1 default color
	
 
SWPSCR	CLR R0
	LI R1,GPBUFF
	LI R2,>0100
	LI R3,6
SWPSC1	MOVB *R11+,R0
	BLWP @VMBR
	MOVB *R11+,R0
	BLWP @VMBW
	DEC R3
	JNE SWPSC1
	
SWPSC3	MOV *R11+,R0
	JEQ SWPSC4
	BLWP @VWTR
	JMP SWPSC3
 
SWPSC4	B *R10
***********************************
*subroutine to copy chardefs at startup to different location
*and set to inverse video (CF7)
*****
INVID	LI R0,>0F00	\
	LI R1,GPBUFF
	LI R2,256
CHRSE2	AI R0,>0500
	BLWP @VMBR
	MOV R1,R3
CHRSE3	INV *R3+	  inverse video
	CI R3,GPBUFF+256
	JLT CHRSE3
	AI R0,>FC00	->400
	BLWP @VMBW
	CI R0,>1200
	JLT CHRSE2	/
	SETO @VSFLAG
	B *R11	
 
 
*****************************
*CALL LINK("WINDOW",R1,C1,R2,C2)
*****************************
WINDOW	C *R13,R15		were any values passed?
	JLT WINDO1		if lt then values were passed
	BL @DFWNDW		set default window values
	JMP CHRSRT
	
WINDO1	BL @GET4
WINDO3	MOV *R3,R3
	MOV *R4,R4
	MOV *R5,R5
	MOV *R6,R6
	MOV R4,@WLCOL
	MOV R6,@WRCOL
	S R3,R5
	INC R5
	MOV R5,@WHIGHT
	S R4,R6
	INC R6
	MOV R6,@WWIDTH
	DEC R3
	SLA R3,5
	A R4,R3
	DEC R3
	MOV R3,@WFRSTR
	DEC R5
	SLA R5,5
	A R3,R5
	MOV R5,@WLASTR
WINDO2	JMP CHRSRT
*****************
DWIND	DATA >0018
	DATA >0020
	DATA >02E0	default values for window
	DATA 1
	DATA 32
	DATA 0
******************
WHIGHT	DATA 0
WWIDTH	DATA 0
WLASTR	DATA 0
WLCOL	DATA 0
WRCOL	DATA 0
WFRSTR	DATA 0
 
DFWNDW	LI R1,WHIGHT
DFWND1	MOV @-12(R1),*R1+
	JNE DFWND1
	B *R11
******************************
***************************************
*CHSET2 restores the character definitions
*CHSETL sets large characters plus lower case (CF7)
***************************************
HX0018	DATA >0018
 
CHSETL	DECT @CHRSED	CHRSE1 now is >0016
 
CHSET2	LI R0,>1400
	BL @GPLCHR
CHSET3	BL @INVID
CHRSRT	B @RTN		back to compiler for next inst.

GPLCHR	MOV R0,@FAC
	BLWP @GPLLNK
CHRSED	DATA >0018	small capital letters
	MOV @HX0018,@CHRSED
	AI R0,>0200
	MOV R0,@FAC
	BLWP @GPLLNK
	DATA >004A	lower case letters
	B *R11

*****************************************
*equivalent of call char in xb (CF7)
*****************
CHAR	LI R0,>0060		after SLA r0 will be >0300
	JMP CHAR2A
	
CHAR2  LI R0,>0260		when SLA R0,3 will be >1300
CHAR2A	BL @GET2
	A *R5,R0		add ascii of character to R0
*	ANDI R0,>00FF		0 to 255
	SLA R0,3		x8 and R0 points to chardef in vdp
	
	MOV *R6,R6
	MOVB *R6+,R5
       SRL R5,8			length is in R5
 
CHAR2B	LI R9,8		will write 8 bytes to VDP
	ANDI R0,>F7FF		keep from going over >1800
	CLR R1
CHAR2C	BL @HEXDEC
       MOVB R4,R1
       SLA R1,4
       BL @HEXDEC
       AB R4,R1
	BL @VSBW		write the byte
       INC R0
 	DEC R9			have to write bytes in multiples of 8
       JNE CHAR2C
       MOV R5,R5		at end of string?
       JGT CHAR2B		go back for 8 more bytes
       C *R13,R15		get here if have written all of string
	JGT CHRSRT		if Gt no more defs to write, back to comp.
CHAR2E	CI R0,>1000		doing CHAR or CHAR2?
	JLT CHAR
	JMP CHAR2
**********************
HEXDEC	DEC R5
	JLT HEXDE3
	MOVB *R6+,R4
	AI R4,->3000
	CI R4,>1000
	JLT HEXDE2
	AI R4,->0700
HEXDE2	B *R11
HEXDE3	CLR R4
	B *R11
****************************	
DELAY	BL @GET1
	MOV *R6,R6
	
	AI R6,8		\		
	LI R4,6
	MPY R4,R6	  This can be shared with SOUND in runtime
	LI R4,100
	DIV R4,R6	/
	
DELAY1	MOVB @>8379,R3
DELAY2	LIMI 2
	LIMI 0
	CB @>8379,R3
	JEQ DELAY2
	DEC R6
	JGT DELAY1
	JMP CHRSRT
 
***************************
*CALL LINK("HILITE",ROW,COL,LEN)
**************************
HX8080	DATA >8080
HILITE	CLR R1
	BL @GET3
	MOV *R6,R2	length for VMBW & VMBR
	MOV *R4,R0
	DEC R0
	SLA R0,5
	A *R5,R0
	DEC R0
	
	LI R3,768	\
	S R0,R3
	C R3,R2		  Keeps from going off bottom
	JGT HILIT1
	MOV R3,R2	/
	
HILIT1	LI R1,GPBUFF
	BLWP @VMBR
	BL @INVTXS
	JMP CHRSRT	97 words up
	
INVTXS	MOV R1,R3
	MOV R2,R6
INVTX1	MOV *R3,R4
	XOR @HX8080,R4
	MOV R4,*R3+
	DECT R6
	JGT INVTX1
	BLWP @VMBW
	B *R11
 
******************************
*CALL LINK("SCRLLF",N) omit n for cir. scroll; any number to fill w/ spaces
******************************
SCRLLF	BL @SCRLFS
SCRLF1	BLWP @VMBR
	MOV R6,R6
	JNE SCRLF2
	MOVB R8,@GPBUFF+50
SCRLF2	MOVB @GPBUFF+50,@GPBUFF+50(R7)
	A R5,R1
	BLWP @VMBW
	S R5,R1
	A R9,R0
*	LIMI 2
*	LIMI 0
	DEC R4
	JNE SCRLF1
SCRLF4	B @RTN
 
*****************************
*CALL LINK("SCRLRT",n)
*****************************
SCRLRT	BL @SCRLFS
	NEG R5			-1
	NEG R7			-LENGTH
	S R2,R1
	INC R1
	JMP SCRLF1
	
SCRLFS	MOV @WFRSTR,R0
	LI R1,GPBUFF+50
	MOV @WWIDTH,R2
	MOV @WHIGHT,R4
	
	CLR R6
	C *R13,R15		see if a number was passed
	JGT SCRLS1		if GT then no number
	MOV *R13+,R6		R6<>0 and inct r13
	
SCRLS1	LI R5,1
	MOV R2,R7
	LI R8,>8080
	LI R9,32
	LI R10,128
	B *R11
 
************************
*CALL LINK("SCRLUP",N)
***********************
SCRLUP	BL @SCRLFS
SCRUP5	MOV R6,R6
	JNE SCRUP1
	BL @SPACES
	JMP SCRUP2
SCRUP1	BLWP @VMBR
SCRUP2	A R10,R1
SCRUP3	DEC R4
	JEQ SCRUP4
	A R9,R0
	BLWP @VMBR
	S R9,R0
	BLWP @VMBW
*	LIMI 2
*	LIMI 0
	A R9,R0
	JMP SCRUP3
SCRUP4	S R10,R1
	BLWP @VMBW
	JMP SCRLF4 	BACK
	
SPACES	CLR R3
SPACE1	MOVB @HX8080,@GPBUFF+50(R3)
	INC R3
	C R3,R2
	JLT SPACE1
	B *R11
 
************************
*CALL LINK("SCRLDN",N)
***********************
SCRLDN	BL @SCRLFS
	MOV @WLASTR,R0
	NEG R9
	JMP SCRUP5
*******************************************	
********************(CF7)
*CALL LINK(SCPXLF,ASCII,LENGTH,#BITS,OPTIONAL STUFF)
SCPXLF	BL @SCPXSB
SCPXL2	MOVB @8(R1),@WKSP+13
	MOVB *R1+,R6
	SLA R6,0
	MOVB R6,@>8C00
	DEC R2
	JNE SCPXL2
	JMP SCPXLF
********************
*CALL LINK(SCPXRT,ASCII,LENGTH,#BITS,OPTIONAL STUFF)
SCPXRT	BL @SCPXSB
SCPXR2	MOVB @-8(R1),R6
	MOVB *R1+,@WKSP+13
	SRL R6,0
	MOVB @WKSP+13,@>8C00
	DEC R2
	JNE SCPXR2
	JMP SCPXRT
************************************
*CALL LINK(SCPXUP,ASCII,LENGTH,#BITS,OPTIONAL STUFF)
SCPXUP	BL @SCPXSB
	A R0,R1
SCPXU2	MOVB *R1+,@>8C00
	DEC R2
	JNE SCPXU2
	JMP SCPXUP
************************************
*CALL LINK(SCPXDN,ASCII,LENGTH,#BITS,OPTIONAL STUFF)
SCPXDN	BL @SCPXSB
	S R0,R1
SCPXD2	MOVB *R1+,@>8C00
	DEC R2
	JNE SCPXD2
	JMP SCPXDN
	
 
 
SCPXSB	C *R13,R15		more arguments in list?
	JGT SCPXS8		if Gt we are done, go back
	MOV R11,R12		store return address
	BL @GET3
	MOV *R4,R0		ASCII is now in R0
	AI R0,>0260		>60 xb offset plus patt table/8
	ANDI R0,>FEFF		0 to 255
	SLA R0,3		x8
	MOV *R5,R2		# chars is in r2
	SLA R2,3		8 bytes per char
SCPXS2	LI R1,GPBUFF+8
	BLWP @VMBR
*	LIMI 2
*	LIMI 0	
	MOVB @WKSP+1,@>8C02	\
	ORI R0,>4000		  set up to write to VDP
	MOVB R0,@>8C02		/
	MOV R1,R3		buffer address to R3
	MOV R2,R4		# bytes read to R4
	A R3,R4		R4 points to next byte after chdefs
SCPXS4	MOV @-8(R4),@-8(R3)	puts last byte in front of 1st byte
	MOV *R3+,*R4+		puts 1st byte after last byte
	CI R3,GPBUFF+16
	JNE SCPXS4		loop till done
	MOV *R6,R0		# bytes to shift
	B *R12
	
SCPXS8	B @RTN
	
****************************************
*CALL LINK("PLAY",ADDRESS
******
PLAY	BL @GET1
	LI R9,>0100
*next is to see if 2nd sound list is to be played
	MOV *R6,R0
	CLR R1
	BLWP @VSBR	Read the first byte(R1 has 1 after the GETNUM
	CI R1,>FD00
	JNE PLAY0
	INC R0
	MOV R0,@MONWS+18	address to R9 of monitor workspace
	MOVB R9,@MONWS+13	byte 1 to R6 monitor ws to start playing
	JMP SCPXS8		and back
	
	
PLAY0	MOV R0,@>83CC
	JEQ NOPLAY
	SOCB R9,@>83FD
PLAY1	MOVB R9,@>83CE
	JMP SCPXS8
	
NOPLAY	LI R2,SNDOFF+1		"PLAY",0 turns off sound
NOPLA1	MOVB *R2+,@>8400
	CI R2,SNDOFF+5
	JNE NOPLA1
	CLR @MONWS+24
	CLR @MONWS+12		R6 of MONWS now is zero to kill player2
	CLR R9
	JMP PLAY1
 
*sndoff  >049F,>BFDF,>FF00  in runtime1
*SNDOFF  DATA >9FBF,>DFFF	OLD value
*********************
FREEZE	SOC @VSBW2+2,@>83C2		>4000
	JMP SCPXS8
THAW	SZC @VSBW2+2,@>83C2
	JMP SCPXS8
**********************
CWRITE	C *R13,R15
	JGT SCPXS8		if Gt we are done, go back
	
	BL @GET1
	MOV *R6,R2		R2 points to string
	MOVB *R2+,R3		length byte to msb r3
	SRL R3,8		length is in R3
	
	A R2,R3		R4 points one past last char in string
	MOVB @HX0001,*R3	put a zero there for a flag
	
	MOVB *R2+,R5		msb of address to msb r5
	MOVB *R2,@WKSP+11	lsb of address to lsb r5
	
	MOVB *R2+,@>8C02
	ORI R5,>4000
	MOVB R5,@>8C02	ready to write!
	
CWRIT8	CI R5,>4780	\
	JLT CWRIT1	  writing to sprite motion table?
	CI R5,>47EF
	JGT CWRIT1	/
	
	MOVB *R2+,@>837A	update # sprites in motion
 
CWRIT1	MOVB *R2+,R5		Length to r5
	JEQ CWRITE		back if length is zero
	SRL R5,8
	CI R5,128
	JLT CWRIT2
	
	ANDI R5,>007F
CWRIT3	MOVB *R2,@>8C00
	DEC R5
	JGT CWRIT3
	INC R2
	JMP CWRIT1
	
CWRIT2	MOVB *R2+,@>8C00
	DEC R5
	JGT CWRIT2
	JMP CWRIT1
**************
 
